<template>
  <div :key="ruleTreeData.currentGroup" class="filter-rules-wrap">
    <div>
      <div v-if="ruleTreeData.children.length > 1" :class="[isRootNode ? 'rules-line-wrap' : 'rules-line-wrap rules-line-left']">
        <div class="toggle-rules-wrap" @click="toggleRules">
          <span class="text">{{ conditionRelation === "or" ? "或" : "且" }}</span>
          <el-icon size="12" class="icon">
            <DCaret />
          </el-icon>
        </div>
      </div>
      <div :class="[isRootNode ? 'main' : 'main main-border', mainStyle]">
        <template v-for="(item, index) in ruleTreeData.children">
          <el-row
            v-if="item.type == 'condition'"
            :key="item.currentGroup"
            :class="[ruleTreeData.children.length === 1 ? 'child' : 'child child-pl']"
          >
            <el-form ref="ruleFormRef" :model="item" :rules="getRulesForItem(item)" :inline="true">
              <el-form-item label="" prop="conditionKey">
                <el-select
                  v-model="item.conditionKey"
                  class="form-item-cell"
                  placeholder="请选择筛选项"
                  @change="changeConditionKeySelect(item)"
                >
                  <el-option v-for="obj in state.filterItems" :key="obj.dictKey" :label="obj.dictName" :value="obj.dictKey" />
                </el-select>
              </el-form-item>
              <el-form-item label="" prop="conditionType">
                <el-select
                  v-model="item.conditionType"
                  placeholder="请选择运算符"
                  class="form-item-cell"
                  @change="changeConditionTypeSelect(item)"
                >
                  <el-option v-for="obj in state.operatorList" :key="obj.dictKey" :label="obj.dictName" :value="obj.dictKey" />
                </el-select>
              </el-form-item>
              <el-form-item label="" prop="conditionValue" style="margin-right: 0">
                <component
                  :is="getConditionValueComponent(item.conditionKey)"
                  v-model="item.conditionValue"
                  class="form-item-cell"
                  :placeholder="getConditionValuePlaceholder(item.conditionKey)"
                  @keyup.enter="handleConditionValueBlur(item.conditionValue, item)"
                  @blur="handleConditionValueBlur(item.conditionValue, item)"
                  @change="handleConditionValueChange(item)"
                  remote
                  reserve-keyword
                >
                  <el-option
                    v-for="opt in getConditionValueOptions(item.conditionKey)"
                    :key="opt.value"
                    :label="opt.label"
                    :value="opt.value"
                  />
                </component>
              </el-form-item>
            </el-form>
            <div style="flex-1"></div>
            <!-- 每一项的清空icon -->
            <div class="svgBox1" @click="removeRuleRow(index)" v-if="index !== 0">
              <img src="@/assets/svg/clear.svg" alt="" />
            </div>
          </el-row>
          <el-row
            v-if="item.type == 'group' && item.children.length > 0"
            :key="item.currentGroup"
            :class="[ruleTreeData.children.length === 1 ? 'child' : 'child child-pl']"
          >
            <filter-rules
              ref="filterRulesRef"
              v-model:modelValue="ruleTreeData.children[index]"
              :filterItemsArray="state.filterItems"
              :operatorArray="state.operatorList"
              @on-change="() => emits('on-change')"
              @on-remove="handleRemoveBack"
            ></filter-rules>
          </el-row>
        </template>

        <div v-if="isRootNode && ruleTreeData.children.length > 0" class="add-wrap">
          <div class="left" @click="addRuleRow">
            <div class="svgBox">
              <img src="@/assets/svg/CirclePlus.svg" alt="" />
            </div>
            <span class="text"> 添加筛选条件 </span>
          </div>
          <div class="left ml-[82px]" @click="addRuleGroup">
            <div class="svgBox">
              <img src="@/assets/svg/CirclePlus.svg" alt="" />
            </div>
            <span class="text"> 添加筛选组条件 </span>
          </div>
          <div class="flex-1"></div>
        </div>

        <div v-else class="add-wrap">
          <div class="left" @click="addRuleRow">
            <div class="svgBox">
              <img src="@/assets/svg/CirclePlus.svg" alt="" />
            </div>
            <span class="text"> 添加筛选条件 </span>
          </div>
          <div class="left ml-[82px]" @click="addRuleGroup">
            <div class="svgBox">
              <img src="@/assets/svg/CirclePlus.svg" alt="" />
            </div>
            <span class="text"> 添加筛选组条件 </span>
          </div>
          <div class="flex-1"></div>
        </div>
      </div>
    </div>
    <!-- 筛选组移除 -->
    <template v-if="!disabled">
      <!-- 每一筛选组的清空icon -->
      <div class="remove-group-icon svgBox1" @click="removeRuleGuop" v-if="!isRootNode">
        <img src="@/assets/svg/clear.svg" alt="" />
      </div>
    </template>
  </div>
</template>

<script lang="ts" setup>
import { isEmpty } from "lodash-es";
import { v4 as uuidv4 } from "uuid";
import { FormInstance } from "element-plus";
import { ref, reactive, watch, onMounted, computed } from "vue";
import dayjs from "dayjs";
import {
  staffStatus,
  educationalBackground,
  schoolSign,
  officialLevel,
  appointmentType,
  staffManagementJurisidiction,
  isOverseas
} from "./constants.ts";
import { filterItems, operatorList } from "./data.ts";

defineOptions({
  name: "FilterRules"
});

const emits = defineEmits(["update:modelValue", "on-remove", "on-change"]);

const props = defineProps({
  modelValue: {
    type: Object,
    default: () => ({})
  },
  type: {
    type: String,
    default: ""
  },
  filterItemsArray: {
    type: Array,
    default: () => []
  },
  operatorArray: {
    type: Array,
    default: () => []
  }
});

export interface ListItem {
  dictName: string | null;
  dictKey: string;
  type: string;
  [key: string]: any;
}

const filterRulesRef = ref<any>();
const ruleFormRef = ref<FormInstance>();
const ruleTreeData = ref<any>({});
const conditionRelation = ref<string>("");
const isRootNode = ref<boolean>(false);
const disabled = ref<boolean>(false);
const parrentGroup = ref<string>("");

const state = reactive({
  isFilterLoading: false,
  isOperatorLoading: false,
  filterItems: [] as ListItem[],
  operatorList: [] as ListItem[]
});

// 是否为根节点
const mainStyle = computed(() => {
  if (isRootNode.value && ruleTreeData.value.children.length > 1) {
    return "main-pl";
  }
  return "";
});

watch(
  () => props.modelValue,
  newVal => {
    setDefaultData(newVal);
  },
  { immediate: true }
);

onMounted(() => {
  initOptions();
});

function initOptions() {
  if (props.filterItemsArray.length) {
    state.filterItems = props.filterItemsArray as any[];
  } else {
    queryFilterItems();
  }
  if (props.operatorArray.length) {
    state.operatorList = props.operatorArray as any[];
  } else {
    queryOperator();
  }
}

// 数据列名列表
async function queryFilterItems(val?: string) {
  try {
    state.isFilterLoading = true;
    setTimeout(() => {
      console.log(val);
      state.filterItems = filterItems;
    }, 1000);
    state.isFilterLoading = false;
  } catch (error) {
    state.isFilterLoading = false;
  }
}

// 运算符列表
async function queryOperator(val?: string) {
  try {
    state.isOperatorLoading = true;
    console.log(val);
    setTimeout(() => {
      state.operatorList = operatorList;
    }, 1000);
    state.isOperatorLoading = false;
  } catch (error) {
    state.isOperatorLoading = false;
  }
}

// 反选
function setDefaultData(newVal: any) {
  if (isEmpty(newVal)) {
    isRootNode.value = true;
    parrentGroup.value = uuidv4();
    conditionRelation.value = "or";
    ruleTreeData.value = {
      currentGroup: parrentGroup.value,
      conditionRelation: conditionRelation.value,
      children: [
        {
          currentGroup: uuidv4(),
          parrentGroup: parrentGroup.value,
          conditionKey: "",
          conditionKeyName: "",
          conditionType: "",
          conditionTypeName: "",
          conditionValue: "",
          type: "condition",
          conditionValueChineseName: "",
          tableName: ""
        }
      ]
    };
    emits("update:modelValue", ruleTreeData.value);
  } else {
    isRootNode.value = !Object.prototype.hasOwnProperty.call(newVal, "parrentGroup");
    parrentGroup.value = newVal.currentGroup;
    ruleTreeData.value = newVal;
    conditionRelation.value = ruleTreeData.value.conditionRelation;
  }
}

// 添加筛选条件
function addRuleRow() {
  ruleTreeData.value.children.push({
    currentGroup: uuidv4(),
    parrentGroup: parrentGroup.value,
    conditionKey: "",
    conditionKeyName: "",
    conditionType: "",
    conditionTypeName: "",
    conditionValue: "",
    type: "condition",
    conditionValueChineseName: "",
    tableName: ""
  });
  emits("update:modelValue", ruleTreeData.value);
}

// 移除筛选条件
function removeRuleRow(index: number) {
  ruleTreeData.value.children.splice(index, 1);
  if (ruleTreeData.value.children.length) {
    emits("update:modelValue", ruleTreeData.value);
    emits("on-change");
  } else {
    emits("on-remove", ruleTreeData.value);
  }
}

// 添加筛选组条件
function addRuleGroup() {
  const currentGroup = uuidv4();
  ruleTreeData.value.children.push({
    conditionRelation: "or",
    type: "group",
    currentGroup,
    parrentGroup: parrentGroup.value,
    children: [
      {
        currentGroup: uuidv4(),
        parrentGroup: currentGroup,
        conditionKey: "",
        conditionKeyName: "",
        conditionType: "",
        conditionTypeName: "",
        conditionValue: "",
        type: "condition",
        conditionValueChineseName: "",
        tableName: ""
      }
    ]
  });
  emits("update:modelValue", ruleTreeData.value);
}

// 移除筛选组条件
function removeRuleGuop() {
  emits("on-remove", ruleTreeData.value);
}

// 处理移除回调
function handleRemoveBack(data: any) {
  const index = ruleTreeData.value.children.findIndex((v: any) => v.currentGroup === data.currentGroup);
  if (index >= 0) {
    ruleTreeData.value.children.splice(index, 1);
    emits("update:modelValue", ruleTreeData.value);
    emits("on-change");
  }
}

// 切换查询条件（or 或者 and）
function toggleRules() {
  conditionRelation.value = conditionRelation.value === "or" ? "and" : "or";
  ruleTreeData.value.conditionRelation = conditionRelation.value;
  emits("on-change");
}

function getRulesForItem(item) {
  console.log("item", item);

  return {
    conditionKey: [{ required: true, message: "请选择", trigger: ["blur", "change"] }],
    conditionType: [{ required: true, message: "请选择", trigger: ["blur", "change"] }],
    conditionValue:
      item.conditionType === "empty" || item.conditionType === "unempty"
        ? []
        : [
            {
              required: true,
              message: "目标值不能为空",
              trigger: ["blur", "change"]
            }
          ]
  };
}

// 列名change
function changeConditionKeySelect(data: any) {
  const item = state.filterItems.find((v: any) => v.dictKey === data.conditionKey);
  if (item) {
    data.conditionKeyName = item.dictName;
    data.tableName = item.tableName; // 设置 tableName 值
    // 清空目标值
    data.conditionValue = "";
  }
  if (data.conditionType) emits("on-change");
}

// 运算符change
function changeConditionTypeSelect(data) {
  const item = state.operatorList.find(v => v.dictKey === data.conditionType);

  if (item) {
    data.conditionTypeName = item.dictName;

    // 清除目标值的校验状态
    if (Array.isArray(ruleFormRef.value)) {
      ruleFormRef.value.forEach(form => form.clearValidate(["conditionValue"]));
      // 清空目标值
      data.conditionValue = "";
    } else if (ruleFormRef.value) {
      ruleFormRef.value.clearValidate(["conditionValue"]);
      // 清空目标值
      data.conditionValue = "";
    }

    emits("on-change");
  }
}

// 目标值change
function handleConditionValueBlur(val: string, item: any) {
  if (val) {
    // 如果是日期选择器，转换日期格式
    if (getConditionValueComponent(item.conditionKey) === "el-date-picker") {
      item.conditionValue = dayjs(val).format("YYYY-MM-DD");
    }
    emits("on-change");
  }
}
// 把对应的枚举类型的label传递给conditionValueChineseName字段
// 目标值change
function handleConditionValueChange(item: any) {
  const options = getConditionValueOptions(item.conditionKey);
  const selectedOption = options.find(opt => opt.value === item.conditionValue);

  if (selectedOption) {
    // 使用选项的label作为中文名
    item.conditionValueChineseName = selectedOption.label;
  } else {
    item.conditionValueChineseName = dayjs(item.conditionValue).format("YYYY-MM-DD");
  }
  emits("on-change");
}

// 表单验证
async function validate() {
  const formList: any = ruleFormRef.value;
  const rulesRefList: any = filterRulesRef.value;
  const list: any[] = [];
  if (Array.isArray(formList)) {
    await Promise.all(
      formList.map(async (item: any) => {
        const valid = await item.validate();
        list.push(!!valid);
      })
    ).catch(() => {
      list.push(false);
    });
  } else if (formList) {
    // 单个表单项
    const valid = await formList.validate().catch(() => {});
    list.push(!!valid);
  }
  // 验证rulesRefList中的每个项;
  if (Array.isArray(rulesRefList)) {
    await Promise.all(
      rulesRefList.map(async (item: any) => {
        const valid = await item.validate();
        list.push(!!valid);
      })
    ).catch(() => {
      list.push(false);
    });
  }
  return list.length !== 0 && list.some((v: boolean) => !v) === false;
}

// 获取 conditionValue 对应的组件类型
function getConditionValueComponent(conditionKey: string) {
  const item = state.filterItems.find(v => v.dictKey === conditionKey);
  if (item) {
    switch (item.type) {
      case "枚举":
        return "el-select";
      case "时间":
        return "el-date-picker";
      case "树形":
        return "el-tree-select";
      default:
        return "el-input";
    }
  }
  return "el-input";
}

// 获取 conditionValue 的占位符
function getConditionValuePlaceholder(conditionKey: string) {
  const item = state.filterItems.find(v => v.dictKey === conditionKey);

  if (item) {
    switch (item.type) {
      case "枚举":
        return "请选择目标值";
      case "树形":
        return "请选择目标值";
      case "时间":
        return "请选择日期";
      default:
        return "请输入目标值";
    }
  }
  return "请输入目标值";
}

// 获取 conditionValue 的选项（仅在 select 类型时使用）
function getConditionValueOptions(conditionKey: string) {
  const item = state.filterItems.find(v => v.dictKey === conditionKey);

  // 检查 item 是否存在且类型为 '枚举'
  if (item && item.type === "枚举") {
    // 创建一个映射对象，将 dictKey 映射到对应的选项列表
    const optionsMap: Record<string, any[]> = {
      "el.staff_status": staffStatus,
      "se.educational_background": educationalBackground,
      school_sign: schoolSign,
      "el.official_level": officialLevel,
      appoint_type: appointmentType,
      "el.staff_management_jurisidiction": staffManagementJurisidiction,
      is_overseas: isOverseas
    };
    // 根据 dictKey 查找对应的选项列表
    return optionsMap[item.dictKey] || [];
  }
  return [];
}

defineExpose({ validate, initOptions });
</script>

<style scoped lang="scss">
.filter-rules-wrap {
  position: relative;
  min-width: 520px;
}

.rules-line-wrap {
  position: absolute;
  top: 30px;
  bottom: 82px;
  left: 8px;
  z-index: 999;
  width: 20px;
  border: rgba(229, 230, 235, 1) solid 1px;
  border-right: 0;
  border-radius: 2px;
  display: flex;
  align-items: center;
  justify-content: center;

  .toggle-rules-wrap {
    display: flex;
    align-items: center;
    width: 30px;
    height: 30px;
    background: #fff;
    border-radius: 50%;
    font-size: 12px;
    cursor: pointer;

    .text {
      margin-right: 6px;
    }

    .icon {
      position: relative;
      left: -5px;
    }
  }
}

.rules-line-left {
  left: 20px;
}

.rules-line-bottom {
  bottom: 32px;
}

.main {
  min-width: 594px;
  width: max-content;
  min-height: 70px;
  padding: 10px 10px 10px 0;
  position: relative;
}

.main-border {
  padding-left: 20px;
  padding-right: 40px;
  border: rgba(229, 230, 235, 1) solid 1px;
  border-radius: 8px;
}

.main-pl {
  padding-left: 15px;
}

.child {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  width: max-content;
  position: relative;
  padding: 10px 0;
}

.child-pl {
  padding-left: 25px;
}

.add-wrap {
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: #0088ff;
  font-size: 12px;
  margin-top: 25px;

  .left {
    display: flex;
    align-items: center;

    .svgBox {
      width: 24px;
      height: 24px;
      cursor: pointer;

      img {
        width: 100%;
      }
    }
  }

  .text {
    margin-left: 4px;
    cursor: pointer;
    color: rgba(42, 130, 228, 1);
    font-size: 14px;
    line-height: 150%;
  }

  .clear-filter {
    display: flex;
    align-items: center;
  }
}

.remove-group-icon {
  position: absolute;
  right: -34px;
  top: 50%;
  transform: translateY(-50%);
  margin-left: 10px;
}

.pointer {
  cursor: pointer;
}

.remove-icon {
  margin-left: 10px;
  cursor: pointer;
}

.form-item-cell {
  width: 150px;
}

.form-item-cell:nth-child(2n + 1) {
  width: 200px;
}

.form-item-cell:nth-child(2),
.form-item-cell:nth-child(3) {
  margin-left: 10px;
}

.svgBox1 {
  width: 24px;
  height: 24px;
  cursor: pointer;
  margin-left: 20px;

  img {
    width: 100%;
  }
}
</style>
